package SVG::Comic::Panel;

use strict;
use warnings;
use Carp;
use vars qw($VERSION $AUTOLOAD);
use SVG::Comic::Character;

$VERSION = '0.1.1';

my %fields = (
	height     => undef,
	width      => undef,
	bgcolor    => 'white',
	textcolor  => 'black',
	fontsize   => 10,
	dialogue   => [],
	id         => 0,
	x          => 0,
	y          => 0,
);

my $_COUNT;
my $_SPECIAL_WIDTH;
my $_SPECIAL_COUNT;
my %_CHARACTERS;

sub new ($;@) {
	my ($this, %attrs) = @_;
	my $class = ref $this || $this;
	my $self;
	
	foreach my $attr (keys %fields) {
		$attrs{$attr} ||= $fields{$attr};
	}
	
	$self = {
		_permitted => \%fields,
		%attrs,
	};
	
	bless $self, $class;
	
	$self->initialize();
	
	return $self;
}

sub initialize {
	my $self = shift;
	
	$SVG::Comic::Panel::_COUNT += 1;
	$SVG::Comic::Panel::_SPECIAL_WIDTH += $self->width || 0;
	$SVG::Comic::Panel::_SPECIAL_COUNT += 1 if $self->width;
	$self->id($SVG::Comic::Panel::_COUNT);
}

sub get_count {
	return $SVG::Comic::Panel::_COUNT || 0;
}

sub get_special_width {
	return $SVG::Comic::Panel::_SPECIAL_WIDTH || 0;
}

sub get_special_count {
	return $SVG::Comic::Panel::_SPECIAL_COUNT || 0;
}

sub add_dialogue {
	my $self = shift;
	my $line = shift;
	
	push (@{$self->dialogue}, $line);
}

sub display {
	my $self = shift;
	my $svg  = shift;
	
	my $pane_g = $svg->group(
			id     => 'panel' . $self->id,
			x      => $self->x,
			y      => $self->y,
			width  => $self->width,
			height => $self->height,
			maskUnits => 'userSpaceOnUse',
		);
		
	my $panel = $pane_g->rect(
			x      => $self->x,
			y      => $self->y,
			height => $self->height,
			width  => $self->width,
			fill   => $self->bgcolor,
		);
		
	my $lines = @{$self->dialogue};
	
	my $y = 0;
	
	my $char_iter = 0;
	
	foreach (my $i = 0; $i < $lines; $i += 2) {
		my $char_name = $self->dialogue->[$i];
		print STDERR $char_name, " $i\n";
		unless ($_CHARACTERS{$char_name}) {
			$_CHARACTERS{$char_name} = $char_iter ;
			$char_iter += 2;
		}
		my $character = SVG::Comic::Character->new(
				character => $char_name,
				x         => $self->x,
				y         => $self->y,
				z         => $_CHARACTERS{$char_name},
				pan_width => $self->width,
				pan_height => $self->height,
			);
		$character->display($pane_g);
		my $dialogue = $self->dialogue->[$i+1];
		my $extra = $self->_display_line($pane_g, $dialogue, $y, $_CHARACTERS{$char_name});
		$y += $extra + 1;
	}
	
	$svg->comment(
		"\n\tGenerated using the Perl " . ref($self) . " Module V" . $VERSION .
		"\n\tby Jacob P. Silvia." .
		"\n\tInfo: http://jacob.silvia.googlepages.com/\n",
		);
}

sub _display_line {
	my $self     = shift;
	my $svg      = shift;
	my $dialogue = shift;
	my $y        = shift;
	my $z        = shift;
	
	my @dialogue = split(/\s+/, $dialogue);

	my $new_dialogue;
	my $total_len = 0;
	
	my $extra = 1;
	
	while (my $word = shift @dialogue) {
		my $len = $self->_text_length($word) + 1;
		if ($total_len + $len > $self->width) {
			$extra += $self->_display_line($svg, join(" ", $word, @dialogue), $y+1, $z);
			last;
		} else {
			$total_len    += $len;
			$new_dialogue .= $word . " ";
		}
	}

	my $ta = '';
	my $xp = 0;

	if ($z/2 % 2) {	
		$ta = 'end';
		$xp = $self->width - 2;
	}
	
	my $line = $svg->text(
			 x          => $self->x + 1 + $xp,
			 y          => $self->y + $self->fontsize + $y * $self->fontsize + 1,
			'font-size' => $self->fontsize,
			 fill       => $self->textcolor,
			 'text-anchor' => $ta,
		)->cdata(
			$new_dialogue,
		);
		
	return $extra;
}

# _text_length borrowed from Graph::Easy::SVG
sub _text_length {
	use utf8;
	
	my $self = shift;
	my $text = shift;
	
	my $em    = $self->fontsize;
	my $count = length($text);
	my $len   = 0;
	my $match;
	
	$match = $text =~ tr/'`//;
	$len += $match * 0.25 * $em;
	$count -= $match;
	
	$match = $text =~ tr/Iijl~.,;:\|//;
	$len += $match * 0.33 * $em;
	$count -= $match;
	
	$match = $text =~ tr/"Jft\(\)\[\]\{\}//;
	$len += $match * 0.4 * $em;
	$count -= $match;
	
	$match = $text =~ tr/?//;
	$len += $match * 0.5 * $em;
	$count -= $match;
	
	$match = $text =~ tr/crs_//;
	$len += $match * 0.55 * $em;
	$count -= $match;
	
	$match = $text =~ tr/ELPaäevyz//;
	$len += $match * 0.6 * $em;
	$count -= $match;
	
	$match = $text =~ tr/BZFbdghknopqux~üö//;
	$len += $match * 0.65 * $em;
	$count -= $match;
	
	$match = $text =~ tr/KCVXY%//;
	$len += $match * 0.7 * $em;
	$count -= $match;
	
	$match = $text =~ tr/§€//;
	$len += $match * 0.75 * $em;
	$count -= $match;
	
	$match = $text =~ tr/ÜÖÄßHGDSNQU$&//;
	$len += $match * 0.8 * $em;
	$count -= $match;
	
	$match = $text =~ tr/AwO=+<>//;
	$len += $match * 0.85 * $em;
	$count -= $match;
	
	$match = $text =~ tr/W//;
	$len += $match * 0.9 * $em;
	$count -= $match;
	
	$match = $text =~ tr/M//;
	$len += $match * 0.95 * $em;
	$count -= $match;
	
	$match = $text =~ tr/m//;
	$len += $match * 1.03 * $em;
	$count -= $match;
	
	$match = $text =~ tr/@//;
	$len += $match * 1.15 * $em;
	$count -= $match;
	
	$match = $text =~ tr/æ//;
	$len += $match * 1.25 * $em;
	$count -= $match;
	
	$len += $count * $em;
	
	return $len;
}

sub AUTOLOAD {
	my $self = shift; 
	
	my $type = ref($self)
		or croak "$self is not an object.";
	
	my $name =  $AUTOLOAD;
	$name    =~ s/.*://;
	
	unless (exists $self->{_permitted}->{$name}) {
		croak "Can't acces `$name' field in class $type";
	}
	
	if (@_) {
		return $self->{$name} = shift;
	} else {
		return $self->{$name};
	}
}

sub DESTROY {
	my $self = shift;
	
	$SVG::Comic::Panel::_COUNT -= 1;
}

1;